Package ru.dubov.polygontriangulation

Source Code of ru.dubov.polygontriangulation.DivideAndConquerAlgorithm

package ru.dubov.polygontriangulation;

import java.util.ArrayList;
import ru.dubov.primitives.Polygon;
import ru.dubov.primitives.Triangle;

public class DivideAndConquerAlgorithm {
   
    /**
     * O(n^4) worst case (!)
     */
    public static ArrayList<Triangle> triangulate(Polygon p) {
       
        result = new ArrayList<Triangle>();
       
        isClockwise = p.isClockwise();
       
        divideAndConquer(p);
       
        return result;
    }
   
    private static void divideAndConquer(Polygon p) {
       
        if(p.size() < 3) {
            return;
        }
        if(p.size() == 3) {
            result.add(new Triangle(p.get(0), p.get(1), p.get(2)));
            return;
        }
       
        boolean diag = true;
        int start = 0, finish = 0;
        int prev = 0, next = 0;
       
        // Looking for a diagonal - O(n^3)
        outer: for(int i = 0; i < p.size()-1; i++) {
            for (int j = i+2; j < p.size(); j++) {
               
                if (i == j || Math.abs(i-j) == 1 ||
                   (i == p.size()-1 && j == 0) ||
                   (j == p.size()-1 && i == 0)) {
                    continue; // not even a candidate to be a diagonal
                }
               
                start = i;
                finish = j;
                diag = true;
               
                // Test for intersections
                for (int k = 0; k < p.size(); k++) {
                                   
                    if (i != k && j != k && i != (k+1)%p.size() && j != (k+1)%p.size() &&
                        SegmentsIntersect.segmentsIntersect(p.get(i), p.get(j),
                                            p.get(k), p.get((k+1)%p.size()))) {
                        diag = false; break;
                    }
                }
               
               
                // Test whether it is not an outer diagonal
                // See http://stackoverflow.com/questions/4380479/finding-the-diagonals-of-a-polygon
               
                prev = i - 1;
                if (prev < 0) prev += p.size();
                next = (i + 1) % p.size();
                   
                if (p.isConvex(i)) {
                    if (! (SegmentsIntersect.isRightTurn(p.get(i), p.get(j), p.get(next)) ^ isClockwise &&
                            SegmentsIntersect.isRightTurn(p.get(i), p.get(prev), p.get(j)) ^ isClockwise)) {
                        diag = false;
                    }
                } else {
                    if (! (SegmentsIntersect.isLeftTurn(p.get(i), p.get(j), p.get(prev)) ^ isClockwise ||
                            SegmentsIntersect.isLeftTurn(p.get(i), p.get(next), p.get(j)) ^ isClockwise)) {
                        diag = false;
                    }
                }
               
                if (diag) {
                    break outer;
                }
            }
        }
       
       
        divideAndConquer(p.subPolygon(start, finish));
        divideAndConquer(p.subPolygon(finish, start));
    }
   
    static boolean isClockwise;
    private static ArrayList<Triangle> result;
}
TOP

Related Classes of ru.dubov.polygontriangulation.DivideAndConquerAlgorithm

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.